import {SybComponentName} from "@/instance";
import {$el, _vNode, $children, _uid, _isMounted} from "@/instance";
import {commandsFormat, commandName, commandLevel, commandSplit, commandType} from "@/complie/commond";

export const eleToVNode = (instance) => {
  const _toVNode = (element) => {
    let astNode = {};

    if (element.nodeType === Node.COMMENT_NODE) {
      astNode = {type: 'comment', content: element.textContent.trim()};
    }

    if (element.nodeType === Node.TEXT_NODE) {
      astNode = {type: 'text', content: element.textContent.trim()};
    }

    if (element.nodeType === Node.ELEMENT_NODE) {
      const getMapAttrs = (attrs) => {
        const list = [];
        for (const {name, value} of attrs) {
          list.push({name, value})
        }
        return list;
      }
      const instanceChildren = instance[$children], tagName = element.tagName.toLowerCase();
      let isHtmlTag = true;
      const mapAttrs = getMapAttrs(Array.from(element.attributes));


      for (let i = 0; i < instanceChildren.length; i++) {
        const iChild = instanceChildren[i];
        if (iChild[SybComponentName].toLowerCase() === tagName) {
          isHtmlTag = false;
          astNode = {
            tag: 'template',
            attrs: mapAttrs,
            children: [iChild[_vNode]],
          };
          break;
        }
      }

      if (isHtmlTag) {
        astNode = {
          tag: tagName,
          attrs: mapAttrs,
          children: []
        };
      }
      // console.log(astNode, 'eleType template、自定义组件也会走进来')

      extendEleAttr(astNode, element);
      filterByCommandType(astNode.attrs)
      for (const childEle of element.childNodes) {
        const childAstNode = _toVNode(childEle);
        astNode.children.push(childAstNode);
      }
    }

    return astNode;
  }
  // console.log(instance[SybComponentName], instance, '执行')
  instance[_vNode] = _toVNode(instance[$el]);
  instance[_isMounted] = true;
};

// 自定义的Vue属性扩展
function extendEleAttr(astNode) {
  let {attrs} = astNode;
  for (let i = 0; i < attrs.length; i++) {
    const {name, value} = attrs[i];
    if (name.startsWith(commandSplit)) {
      for (let command of commandsFormat) {
        for (let commandValue of command.values) {
          if (commandValue[commandName] === name) {
            // console.log(astNode, 'ff', name, value, commandValue[commandName]);
            attrs[i] = {
              name, value, [commandType]: command.type, [commandLevel]: commandValue[commandLevel]
            }
          }
        }
      }
    }
  }

}

/**
 * 我们先创建一个空对象 `resultMap`，用于存储每个 `commandType` 对应的具有最大 `commandLevel` 的项。
 * 然后，我们遍历给定的数组 `arr`，对每个项进行判断。如果项没有 `commandType` 属性，则继续循环。
 * 如果 `commandType` 不在 `resultMap` 中，或者当前项的 `commandLevel` 大于 `resultMap` 中对应 `commandType` 的项，则我们将当前项添加到 `resultMap`。
 * 接下来，我们倒序遍历原始数组 `arr`，对于具有 `commandType` 属性且和 `resultMap` 中对应的项不同的项，我们将其从数组中删除。
 * 这样，我们直接在原始数组 `arr` 上进行了修改，只保留具有相同 `commandType` 并且具有最大 `commandLevel` 的项。*/
function filterByCommandType(attrs) {
  const resultMap = {};

  for (let i = 0; i < attrs.length; i++) {
    const item = attrs[i];
    if (!item.hasOwnProperty(commandType)) {
      continue;
    }

    if (!resultMap[item[commandType]] || item[commandLevel] > resultMap[item[commandType]][commandLevel]) {
      resultMap[item[commandType]] = item;
    }
  }

  for (let i = attrs.length - 1; i >= 0; i--) {
    const item = attrs[i];
    if (item.hasOwnProperty(commandType) && item !== resultMap[item[commandType]]) {
      attrs.splice(i, 1);
    }
  }
}
